package cn.j2ee.chapter2.web.controller;

import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;

/**
 * 
 * 2016年11月12日上午10:59:22
 */
@Controller
public class LoginController implements ApplicationContextAware {
	private ApplicationContext applicationContext ;
	@Override
	public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
		this.applicationContext = applicationContext;
	}
	@RequestMapping(value = "/")
	@ResponseBody
	public String index() {
		return "index";
	}
	@RequestMapping(value = "/login")
	public ModelAndView login(@RequestParam(name="username",required = true) String name,
			@RequestParam(name="password",required = true) String password) {
		//1、收集参数  
        //2、绑定参数到命令对象  
        //3、调用业务对象  
        Authentication request = new UsernamePasswordAuthenticationToken(name, password);
        AuthenticationManager authenticationManager = new AuthenticationManager() {
			
			@Override
			public Authentication authenticate(Authentication auth) throws AuthenticationException {
				if(auth.getName().equals(auth.getCredentials())){
					return new UsernamePasswordAuthenticationToken(auth.getName(), auth.getCredentials(),null);
				}
				throw new BadCredentialsException("Bad credentials");
			}
		} ;
        String[] beanNames = this.applicationContext.getBeanDefinitionNames();
        for(String beanName : beanNames){
        	System.out.println(beanName);
        }
        SecurityContext securityContext = SecurityContextHolder.getContext();

        if(this.applicationContext.containsBean("authenticationManager")){
        	authenticationManager  = (AuthenticationManager)this.applicationContext.getBean("authenticationManager");
            authenticationManager =  this.applicationContext.getBean(AuthenticationManager.class);
        }
		Authentication authentication = authenticationManager.authenticate(request);
        securityContext.setAuthentication(authentication);
	    authentication = securityContext.getAuthentication();
		if(securityContext != null){
			Object principal = authentication.getPrincipal();
			if(principal instanceof UserDetails){
				String username = ((UserDetails)principal).getUsername();
			}else {
				String username = principal.toString();
			}
		
		
		}
        //4、选择下一个页面  
        ModelAndView mv = new ModelAndView();  
        //添加模型数据 可以是任意的POJO对象  
        mv.addObject("message", "Hello World!");  
        mv.addObject("_csrf.parameterName","yang");
        mv.addObject("_csrf.token", "zhen");
//        mv.addObject("object",body);

        //设置逻辑视图名，视图解析器会根据该名字解析到具体的视图页面  
        mv.setViewName("login");  
        return mv;  
	}
	@RequestMapping(value = "/login.do")
	public ModelAndView loginDo() {
		//1、收集参数  
        //2、绑定参数到命令对象  
        //3、调用业务对象  
        //4、选择下一个页面  
        ModelAndView mv = new ModelAndView();  
        //添加模型数据 可以是任意的POJO对象  
        mv.addObject("message", "Hello World!"); 
        
        //设置逻辑视图名，视图解析器会根据该名字解析到具体的视图页面  
        mv.setViewName("hello");  
        return mv;  
	}
	
	@RequestMapping(value = "/hello")
	public ModelAndView hello() {
		//1、收集参数  
        //2、绑定参数到命令对象  
        //3、调用业务对象  
        //4、选择下一个页面  
        ModelAndView mv = new ModelAndView();  
        //添加模型数据 可以是任意的POJO对象  
        mv.addObject("message", "Hello World!"); 
        
        //设置逻辑视图名，视图解析器会根据该名字解析到具体的视图页面  
        mv.setViewName("hello");  
        return mv;  
	}
	@RequestMapping(value = "/welcome")
	@ResponseBody
	public String welcome() {
		return "welcome";
	}
}
